import React from 'react';
import {get, post} from "../utils";
import {Select, Spin} from "antd";

const Option = Select.Option;

export class SelectSync extends React.Component {

    static getDerivedStateFromProps(nextProps) {
        // Should be a controlled component.
        if ('value' in nextProps) {
            let params = nextProps.params;
            if (params instanceof Function) {
                params = params();
            }
            return {
                // params,
                value: nextProps.value
            };
        }
        return null;
    }

    constructor(props) {
        super(props);
        this.state = {
            dataSource: [],
            isLoading: true,
            value: props.value,
            params: props.params
        };
        this.isNameFunction = props.name instanceof Function;
    }

    componentDidMount() {
        const {isDefaultLoad = true} = this.props;
        if (isDefaultLoad) {
            this.obtainSelectData(this.setDefaultValue);
        }
    }

    setDefaultValue = (list) => {
        const closeDefaultValue = this.props.closeDefaultValue; // 是否关闭显示默认值
        if (list && !closeDefaultValue) {
            // 如果存在默认值的话，显示默认值
            const {value, selectKey, onChange, onRequestFinish, isdefault = true} = this.props;
            let defItemList;
            if (value) {
                defItemList = list.filter(item => item[selectKey] === value);
            } else {
                defItemList = list.filter(item => item.isdefault || item.isdefault === 1);
            }
            if (defItemList.length > 0 && isdefault) {
                const def = defItemList[0];
                const id = def[selectKey];
                onChange(id, {props: {data: def}});
            }
            if (onRequestFinish) onRequestFinish();
        }
    }

    async obtainSelectData(callback) {
        const {params, url, onDataSource} = this.props;
        let reqParams = params;
        if (params instanceof Function) {
            reqParams = params();
        }
        if (!params) {
            reqParams = {};
        }
        if (JSON.stringify(this.reqParams) === JSON.stringify(reqParams)) {
            return null;
        }
        this.reqParams = reqParams;
        this.setState({isLoading: true});
        const {data, state} = await (this.props.type === 'post' ? post : get)(url, reqParams);
        this.setState({isLoading: false});
        if (state === 1) {
            let list = onDataSource ? onDataSource(data, state) : data.list;
            // if (url === requestUrl.SEARCH_ADMIN_LIST) {
            //     const manager_name = app.getData('shop_nick_name');
            //     const admin_id = app.getData('shop_admin_id');
            //     // const admin_username = app.getData('shop_admin_username');
            //     if (manager_name) {
            //         list.unshift({admin_username: manager_name, manager_name: manager_name, key: 0, admin_id});
            //     }
            // }
            this.setState({dataSource: list}, () => callback(list));
            return list;
        }
        return null;
    }

    render() {
        const {dataSource, isLoading, value, closeDefaultValue} = this.state;
        if (closeDefaultValue) {
            this.obtainSelectData(this.setDefaultValue);
        }
        const {
            placeholder,
            name,
            selectKey,
            defaultOpen,
            mode,
            onChange,
            style,
            disabledKeys,
            disabled,
            selectType,
            selectValue,
            allowClear,
            filterOption =
                (input, option) => {
                    if (selectType === 'textNode') {
                        return option.props.children && selectValue(option.props.data).toLowerCase().indexOf(input.toLowerCase()) >= 0;
                    }
                    return option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
                }
        } = this.props;
        // 如果value是对象的话，表示有可能需要显示选择项中不存在的值，这个是用就取show的值，因为有可能选项的值被删除了，但是记录还在
        let selectedValue = value;
        if (value) {
            const typeofValue = typeof value;
            if (typeofValue === 'number' || typeofValue === 'string' || value instanceof Array) {
                selectedValue = value;
            } else {
                const re = dataSource.filter(item => item[selectKey] === value.value);
                if (re.length === 0) {
                    selectedValue = value.show;
                } else {
                    selectedValue = value.value;
                }
            }
        }
        const isNameFunction = this.isNameFunction; // 判断showName是函数，还是对象

        let optionList = dataSource;
        // 把在disabledkeys里的选项去除掉
        if (disabledKeys && disabledKeys.length !== 0) {
            optionList = dataSource.filter(item => {
                return !disabledKeys.includes(item[selectKey]);
            });
        }
        if (isLoading) {
            return (
                <Spin spinning={isLoading}/>
            );
        }
        return (
            <Select
                style={style}
                // allowClear={!allowClear}
                mode={mode}
                defaultOpen={defaultOpen}
                disabled={disabled}
                placeholder={placeholder}
                showSearch
                filterOption={filterOption}
                onChange={onChange} value={selectedValue}
            >
                <Option
                    value={''}
                >全部</Option>
                {
                    optionList.map(item => {
                        const showName = isNameFunction ? name(item) : item[name];
                        const key = item.key || item[selectKey];
                        return (
                            <Option
                                data={item}
                                key={key}
                                value={item[selectKey]}
                            >{showName}</Option>
                        );
                    })
                }
            </Select>
        );
    }
}